﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Clipping.Utils;
using System.IO;
using Clipping.Infrastructure.Models;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Xml;
using Ionic.Zip;
using System.Net;
using System.Threading.Tasks;

namespace ClippingEditor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        Dictionary<string, FieldViewModel> _commonFieldViewModels;

        List<FieldViewModel> _extFieldViewModels = new List<FieldViewModel>();
        List<OptionalFieldViewModel> _extOptionalFieldViewModes = new List<OptionalFieldViewModel>();
        List<MultiSelectOptionalFieldViewModel> _extMultiSelectOptionalFieldViewModes = new List<MultiSelectOptionalFieldViewModel>();

        HashSet<string> commonFields = new HashSet<string>() { "headlineC", "link", "synopsisC", "mediaID", "Section", "mediaDate", "Reporter", "Words", "adValue", "Page", "Width", "Height", "pageSize" };

        private bool _fullchannel = false;//值为true时，提取频道形如 首页>资讯中心，否则形如： 资讯中心

        private SysSettings sysSetting;
        private UserSettings userSetting;
        private Log4cb.ILog4cbHelper logHelper;
        public MainWindow()
        {
            InitializeComponent();
            this.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
        }

        public MainWindow(Clipping.Infrastructure.Models.News news, Log4cb.ILog4cbHelper logHelper = null)
            : this()
        {
            this.News = news;
            if (!string.IsNullOrEmpty(this.News.Title))
                this.Title = this.News.Title;
            if (logHelper != null)
                this.logHelper = logHelper;
            else
                this.logHelper = new Log4cb.Log4cbHelper("ClippingEditor");


        }

        public Clipping.Infrastructure.Models.News News { get; private set; }

        /// <summary>
        /// 快捷键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
        {

            if (Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.LeftShift) && !Keyboard.IsKeyDown(Key.LeftAlt))
            {
                if (e.Key == Key.G)
                {
                    btn_OpenLink_Click(null, null);
                }
                else if (e.Key == Key.W)
                {
                    btn_CountWords_Click(null, null);
                }
                else if (e.Key == Key.R)
                {
                    btn_ExtractContent_Click(null, null);
                }
                else if (e.Key == Key.T)
                {
                    btn_ExtractAllContent_Click(null, null);
                }
                else if (e.Key == Key.I)
                {
                    btn_Snapshot_Click(null, null);
                }

            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            loadSettings();
            if (App.StartAlone)
            {
                if (sysSetting.AutoUpdate)
                {
                    if (!string.IsNullOrEmpty(sysSetting.ClientInfoUrl) || !string.IsNullOrEmpty(sysSetting.UserInfoUrl) || !string.IsNullOrEmpty(sysSetting.MediaInfoUrl))
                    {
                        Settings.InfoFileUpdate updateWin = new Settings.InfoFileUpdate(sysSetting, null);
                        updateWin.ShowDialog();
                    }
                }
            }


            generateFieldViewModels();
            bindFields();
            this.categorySelector.SelectedClientChanged += new Action<ClientInfo>(categorySelector_SelectedClientChanged);
            if (this.News != null)
            {
                if (this.userSetting.AutoOpenNews)
                {
                    btn_OpenLink_Click(null, null);
                }
                if (this.userSetting.AutoGetContent)
                {
                    btn_ExtractAllContent_Click(null, null);
                }
            }
        }

        private void loadSettings()
        {
            SettingRepository rep = new SettingRepository();
            this.sysSetting = rep.GetSysSettings();
            this.userSetting = rep.GetUserSettings();
        }

        void categorySelector_SelectedClientChanged(ClientInfo client)
        {
            LoadExtFields(client);
        }


        private void LoadExtFields(ClientInfo client)
        {
            this.wrapPanel_ExtFields.Children.Clear();
            this._extFieldViewModels.Clear();
            this._extOptionalFieldViewModes.Clear();
            this._extMultiSelectOptionalFieldViewModes.Clear();
            if (client == null)
                return;
            if (client.Fields != null)
            {
                foreach (var field in client.Fields)
                {
                    if (!this.commonFields.Contains(field.Id))
                    {
                        FieldViewModel fvm = new FieldViewModel(field, null);
                        FieldView fv = new FieldView() { DataContext = fvm, Height = 30, MinWidth = 200 };
                        this._extFieldViewModels.Add(fvm);
                        this.wrapPanel_ExtFields.Children.Add(fv);
                    }
                }
            }
            if (client.Properties != null)
            {
                foreach (var opField in client.Properties)
                {
                    if (opField.MultiSelect == false)
                    {
                        OptionalFieldViewModel ofvm = new OptionalFieldViewModel(opField, null);
                        this._extOptionalFieldViewModes.Add(ofvm);
                        OptionalFieldView ofv = new OptionalFieldView() { DataContext = ofvm, Height = 30, MinWidth = 200 };
                        this.wrapPanel_ExtFields.Children.Add(ofv);
                    }
                    else
                    {
                        MultiSelectOptionalFieldViewModel ofvm = new MultiSelectOptionalFieldViewModel(opField, null);
                        this._extMultiSelectOptionalFieldViewModes.Add(ofvm);
                        MultiSelectOptionalFieldView ofv = new MultiSelectOptionalFieldView() { DataContext = ofvm };
                        this.stackPanel_ExtFields_MultiSelectFields.Children.Add(ofv);
                    }
                }
            }
        }

        private void generateFieldViewModels()
        {
            this._commonFieldViewModels = new Dictionary<string, FieldViewModel>();
            string[][] fields = new string[][] { new string[] { "标题", "headlineC" }, new string[] { "链接", "link" }, new string[] { "中文摘要", "synopsisC" } };
            foreach (var f in fields)
            {
                Field field = new Field() { DisplayName = f[0], Name = f[1], Type = FieldType.Field };
                FieldViewModel vm = new FieldViewModel(field, null);
                this._commonFieldViewModels.Add(field.Name, vm);
            }

            string[][] properties = new string[][] { new string[] { "版面", "Section" }, new string[] { "日期", "mediaDate" }, new string[] { "记者", "Reporter" }, new string[] { "字数", "Words" }, new string[] { "广告值", "adValue" }, new string[] { "页面", "Page" }, new string[] { "宽度", "Width" }, new string[] { "高度", "Height" }, new string[] { "页面大小", "pageSize" } };
            Field mediaField = new Field() { DisplayName = "媒体", Name = "mediaID", Type = FieldType.Property };
            MediaFieldViewModel mediaFieldVM = new MediaFieldViewModel(mediaField, null);

            this._commonFieldViewModels.Add(mediaField.Name, mediaFieldVM);

            foreach (var p in properties)
            {
                Field f = new Field() { DisplayName = p[0], Name = p[1], Type = FieldType.Property };

                FieldViewModel vm = new FieldViewModel(f, null);
                this._commonFieldViewModels.Add(f.Name, vm);
            }


            if (this.News != null)
            {
                this._commonFieldViewModels["headlineC"].Value = this.News.Title;
                this._commonFieldViewModels["link"].Value = this.News.Url;

                if (!string.IsNullOrEmpty(this.News.PubDate))
                {
                    DateTime pubDate;
                    if (DateTime.TryParse(this.News.PubDate, out pubDate))
                        this._commonFieldViewModels["mediaDate"].Value = pubDate.ToString("yyyy-MM-dd");
                }
                (this._commonFieldViewModels["mediaID"] as MediaFieldViewModel).TrySetMedia(this.News.Media, this.News.Url);
                if (!string.IsNullOrEmpty(this.News.Summary))
                    this._commonFieldViewModels["synopsisC"].Value = System.Web.HttpUtility.HtmlDecode(this.News.Summary);
            }
            this._commonFieldViewModels["adValue"].Value = this.userSetting.DefaultAD;
            this._commonFieldViewModels["Width"].Value = this.userSetting.DefaultWidth;
            this._commonFieldViewModels["Height"].Value = this.userSetting.DefaultHeight;
            this._commonFieldViewModels["pageSize"].Value = this.userSetting.DefaultPageSize;
            this._commonFieldViewModels["Page"].Value = this.userSetting.DefaultPage;
        }

        private void bindFields()
        {
            Dictionary<string, FieldViewModel> viewModels = this._commonFieldViewModels;
            this.field_headline.DataContext = viewModels["headlineC"];
            this.field_link.DataContext = viewModels["link"];
            this.field_synopsisC.DataContext = viewModels["synopsisC"];
            this.field_media.DataContext = viewModels["mediaID"];
            this.field_section.DataContext = viewModels["Section"];
            this.field_date.DataContext = viewModels["mediaDate"];
            this.field_words.DataContext = viewModels["Words"];
            this.field_adValue.DataContext = viewModels["adValue"];
            this.field_page.DataContext = viewModels["Page"];
            this.field_reporter.DataContext = viewModels["Reporter"];
            this.field_width.DataContext = viewModels["Width"];
            this.field_height.DataContext = viewModels["Height"];
            this.field_pageSize.DataContext = viewModels["pageSize"];

        }


        /// <summary>
        /// 打开链接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_OpenLink_Click(object sender, RoutedEventArgs e)
        {
            var link = getFirstLink();
            if (!string.IsNullOrEmpty(link))
            {
                this.webBrowser.Navigate(link);
                this.tab.SelectedIndex = 1;
            }
        }
        /// <summary>
        /// 发送剪报
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_Click(object sender, RoutedEventArgs e)
        {
            if (!validateInput())
                return;

            if (alreadyUploaded())
            {
                var result = MessageBox.Show(string.Format("该新闻曾上传至本客户下，是否继续？"), "重复上传", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (result == MessageBoxResult.No)
                    return;
            }


            var clipping = generateClipping();
            string filename;
            if (saveClippingLocal(clipping, out filename))
            {
                var titleField = this._commonFieldViewModels["headlineC"] as FieldViewModel;
                UploadProgress win = new UploadProgress(titleField.Value, filename, this.sysSetting.UploadUrl, this.sysSetting.UploadUserName, this.sysSetting.UploadPassword, this.logHelper);
                win.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
                win.Owner = this;
                if (win.ShowDialog() == true)
                {
                    updateHistory();
                    var result = MessageBox.Show("上传剪报成功！是否关闭窗体？", "上传成功", MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (result == MessageBoxResult.Yes)
                        this.Close();
                }
                else
                {
                    MessageBox.Show("上传剪报失败！");
                }
            }
        }
        /// <summary>
        /// 统计字数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_CountWords_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(this.htmlEditor.ContentHtml))
            {
                int words = ClippingHelper.CountWords(this.htmlEditor.ContentHtml);
                var wordsField = this._commonFieldViewModels["Words"] as FieldViewModel;
                wordsField.Value = words.ToString();
            }
        }

        /// <summary>
        /// 插入标题
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_InsertTitle_Click(object sender, RoutedEventArgs e)
        {
            var titleField = this._commonFieldViewModels["headlineC"] as FieldViewModel;
            if (!string.IsNullOrEmpty(titleField.Value))
            {
                if (!string.IsNullOrEmpty(this.htmlEditor.ContentHtml))
                {
                    string str = string.Format("<h1 align=center>{0}</h1>", titleField.Value);
                    if (!Regex.Match(this.htmlEditor.ContentHtml, string.Format("^{0}", Regex.Escape(str)), RegexOptions.IgnoreCase).Success)
                    {
                        this.htmlEditor.ContentHtml = str + this.htmlEditor.ContentHtml;
                    }
                }
            }
        }

        /// <summary>
        /// 获取当前页正文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ExtractContent_Click(object sender, RoutedEventArgs e)
        {

            if (this.webBrowser.Document == null || this.webBrowser.Document.body == null)
                return;
            string content;
            string channel;
            Uri nextpage;
            this.busyIndicator.IsBusy = true;
            try
            {
                NewsParser.GetContent(new Uri(this.webBrowser.Document.url), this.webBrowser.Document.body.innerHTML, 1, out content, out channel, out nextpage);
                if (!string.IsNullOrEmpty(content))
                    this.htmlEditor.Document.Content = content;

                if (!string.IsNullOrEmpty(channel))
                {
                    if (!this._fullchannel)
                    {
                        int index = channel.LastIndexOf(">");
                        if (index > 0 && index < channel.Length - 1)
                        {
                            channel = channel.Substring(index + 1);
                            channel = channel.Trim();
                        }
                    }
                    var channelField = this._commonFieldViewModels["Section"] as FieldViewModel;
                    channelField.Value = channel;
                }

            }
            finally { this.busyIndicator.IsBusy = false; }

        }

        /// <summary>
        /// 连续页获取正文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ExtractAllContent_Click(object sender, RoutedEventArgs e)
        {
            var link = getFirstLink();
            if (!string.IsNullOrEmpty(link))
            {
                this.busyIndicator.IsBusy = true;
                Task.Factory.StartNew(() => { getAllContent(link); });
            }
            else
            {
                MessageBox.Show("不是一个格式良好的网页地址", "地址不正确", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void getAllContent(string link)
        {
            Uri uri = new Uri(link);
            string channel;
            IHtmlDownload donwloader = new HTMLDownloader(true);


            try
            {
                string content = NewsParser.GetContentContinuously(uri, donwloader, out channel);

                if (!string.IsNullOrEmpty(content))
                {
                    if (this.htmlEditor.Document != null)
                    {
                        this.htmlEditor.Document.Content = content;
                    }
                    else
                    {
                        this.htmlEditor.DocumentReady += (s, e1) => { this.htmlEditor.Document.Content = content; };
                    }
                }

                if (!string.IsNullOrEmpty(channel))
                {
                    if (!this._fullchannel)
                    {
                        int index = channel.LastIndexOf(">");
                        if (index > 0 && index < channel.Length - 1)
                        {
                            channel = channel.Substring(index + 1);
                            channel = channel.Trim();
                        }
                    }
                    var channelField = this._commonFieldViewModels["Section"] as FieldViewModel;
                    channelField.Value = channel;
                }
            }
            finally
            {
                DispatcherHelper.InvokeAction(() => { this.busyIndicator.IsBusy = false; });
            }
        }



        /// <summary>
        /// 网页快照
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Snapshot_Click(object sender, RoutedEventArgs e)
        {
            var link = getFirstLink();
            if (!string.IsNullOrEmpty(link))
            {
                Dlg_ImageEditor dlg = new Dlg_ImageEditor(link, addCapPicture);
                dlg.Show();
            }
        }

        /// <summary>
        /// 加入图片列表
        /// </summary>
        /// <param name="bitmap"></param>
        private void addCapPicture(Bitmap bitmap)
        {
            this.picManager.Images.Add(bitmap);
            this.tab.SelectedIndex = 2;
        }

        /// <summary>
        /// 取第一条链接
        /// </summary>
        /// <returns></returns>
        private string getFirstLink()
        {
            var linkField = this._commonFieldViewModels["link"] as FieldViewModel;
            if (!string.IsNullOrEmpty(linkField.Value))
            {
                var lines = Regex.Split(linkField.Value, "[\r\n]+");
                if (lines.Length > 0)
                {
                    if (Uri.IsWellFormedUriString(lines[0], UriKind.Absolute))
                        return lines[0];
                }
            }
            return null;
        }

        private List<string> getLinks()
        {
            List<string> rtn = new List<string>();
            var linkField = this._commonFieldViewModels["link"] as FieldViewModel;
            if (!string.IsNullOrEmpty(linkField.Value))
            {
                var lines = Regex.Split(linkField.Value, "[\r\n]+");
                if (lines.Length > 0)
                {
                    foreach (var line in lines)
                    {
                        if (Uri.IsWellFormedUriString(line, UriKind.Absolute))
                            rtn.Add(line);
                    }
                }
            }
            return rtn;
        }
        /// <summary>
        /// 验证输入
        /// </summary>
        /// <returns></returns>
        private bool validateInput()
        {

            var wordsField = this._commonFieldViewModels["Words"] as FieldViewModel;
            if (string.IsNullOrEmpty(wordsField.Value) || Regex.IsMatch(wordsField.Value, @"[\d]+") == false)
            {
                if (userSetting.AutoCountWords)
                {
                    int words = ClippingHelper.CountWords(this.htmlEditor.ContentHtml);
                    wordsField.Value = words.ToString();
                }
                else
                {
                    wordsField.Value = this.userSetting.DefaultWords;
                }
            }

            if (string.IsNullOrEmpty(sysSetting.UploadUrl))
            {
                MessageBox.Show("未指定上传剪报的HTTP，无法执行上传操作！");
                return false;
            }
            if (categorySelector.SelectedCategories == null || categorySelector.SelectedCategories.Count == 0)
            {
                MessageBox.Show("未指定上传分类，无法执行上传操作！");
                return false;
            }

            var titleField = this._commonFieldViewModels["headlineC"] as FieldViewModel;
            if (string.IsNullOrEmpty(titleField.Value))
            {
                MessageBox.Show("请输入新闻标题。");
                return false;
            }

            var mediaField = this._commonFieldViewModels["mediaID"] as FieldViewModel;
            if (string.IsNullOrEmpty(mediaField.Value))
            {
                MessageBox.Show("请输入新闻媒体。");
                return false;
            }

            var dateField = this._commonFieldViewModels["mediaDate"] as FieldViewModel;
            if (string.IsNullOrEmpty(dateField.Value))
            {
                MessageBox.Show("请输入新闻日期。");
                return false;
            }

            string dateStr = dateField.Value;
            DateTime date;
            if (!DateTime.TryParse(dateStr, out date) && !Regex.IsMatch(dateStr, @"^\d{4}-\d{1,2}-\d{1,2}( \d{2}:\d{2}:\d{2}| \d{2}:\d{2})?$"))
            {
                MessageBox.Show("不是有效的日期格式。");
                return false;
            }

            var pageSizeField = this._commonFieldViewModels["pageSize"] as FieldViewModel;
            string pagesize = pageSizeField.Value;
            if (!Regex.IsMatch(pagesize, @"^\d+/\d+$"))
            {
                MessageBox.Show("页面大小的格式不正确。\n请输入形如 “1/1”，“1/2”，“1/3”...的内容。");
                return false;
            }

            var heightField = this._commonFieldViewModels["Height"] as FieldViewModel;
            string height = heightField.Value;

            if (!Regex.IsMatch(height, @"^\d+(\.\d+)?$"))
            {
                MessageBox.Show("高度的格式不正确。\n请输入数字。");
                return false;
            }
            var widthField = this._commonFieldViewModels["Width"] as FieldViewModel;
            string width = widthField.Value;
            if (!Regex.IsMatch(width, @"^\d+(\.\d+)?$"))
            {
                MessageBox.Show("宽度的格式不正确。\n请输入数字。");
                return false;
            }


            foreach (var vm in this._extOptionalFieldViewModes)
            {
                if (vm.Value == null)
                {
                    MessageBox.Show(string.Format("请选择{0}", vm.Field.Name));
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 检查是否曾经上传过
        /// </summary>
        /// <returns></returns>
        private bool alreadyUploaded()
        {
            var link = getFirstLink();
            try
            {

                UploadHistoryService.getClientIdByLinkPortTypeClient client = new UploadHistoryService.getClientIdByLinkPortTypeClient();
                var clientIds = client.getClientIdByLink(link);

                if (clientIds == null || clientIds.Count == 0)
                {
                    return false;
                }
                else
                {

                    if (clientIds.Contains(this.categorySelector.SelectedCategories.First().Client.Id))
                        return true;
                    else
                        return false;
                }
            }
            catch (Exception ex)
            {
                this.logHelper.LogWarnMsg(ex, "获取已上传分类异常，url={0}", link);
                return false;
            }
        }

        /// <summary>
        /// 生成剪报
        /// </summary>
        /// <returns></returns>
        private XmlDataDocument generateClipping()
        {
            string xmlTemplate = string.Format("<?xml version=\"1.0\" encoding=\"{0}\"?><Clipping><ContentHtml /><ContentTxt /><Pictures /><CapPictures /></Clipping>", this.sysSetting.Encoding);

            XmlDataDocument xmldoc = new XmlDataDocument();
            xmldoc.LoadXml(xmlTemplate);
            XmlElement xe;
            XmlNode rootnode = xmldoc.SelectSingleNode("/Clipping");
            xe = rootnode as XmlElement;
            xe.SetAttribute("ClientId", this.categorySelector.SelectedCategories.First().Client.Id);

            xe = xmldoc.CreateNode(XmlNodeType.Element, "Classes", "") as XmlElement;
            foreach (ClassInfo ci in this.categorySelector.SelectedCategories)
            {
                XmlNode subNode = xmldoc.CreateNode(XmlNodeType.Element, "Class", "");
                XmlNode valueNode = xmldoc.CreateNode(XmlNodeType.Text, "ValueClass", "");
                valueNode.Value = ci.Id;
                subNode.AppendChild(valueNode);
                xe.AppendChild(subNode);

            }
            rootnode.AppendChild(xe);

            foreach (var field in this._commonFieldViewModels)
            {
                if (field.Key == "link")
                {
                    xe = xmldoc.CreateNode(XmlNodeType.Element, "Links", "") as XmlElement;
                    var links = getLinks();
                    if (links != null)
                    {
                        foreach (string l in links)
                        {
                            XmlNode subNode = xmldoc.CreateNode(XmlNodeType.Element, "Link", "");
                            XmlNode valueNode = xmldoc.CreateNode(XmlNodeType.Text, "linkValue", "");
                            valueNode.Value = l;
                            subNode.AppendChild(valueNode);
                            xe.AppendChild(subNode);
                        }
                    }
                    rootnode.AppendChild(xe);
                }
                else
                {
                    xe = xmldoc.CreateNode(XmlNodeType.Element, "Field", "") as XmlElement;
                    xe.SetAttribute("Name", field.Value.Field.Name);
                    xe.SetAttribute("Value", field.Value.Value);
                    rootnode.AppendChild(xe);
                }
            }

            foreach (var field in this._extFieldViewModels)
            {
                xe = xmldoc.CreateNode(XmlNodeType.Element, "Field", "") as XmlElement;
                xe.SetAttribute("Name", field.Field.Name);
                xe.SetAttribute("Value", field.Value);
                rootnode.AppendChild(xe);
            }
            foreach (var field in this._extOptionalFieldViewModes)
            {
                xe = xmldoc.CreateNode(XmlNodeType.Element, "Property", "") as XmlElement;
                xe.SetAttribute("Name", field.Field.Name);
                xe.SetAttribute("Value", field.Value.Id);
                rootnode.AppendChild(xe);
            }
            foreach (var field in this._extMultiSelectOptionalFieldViewModes)
            {
                xe = xmldoc.CreateNode(XmlNodeType.Element, "Property", "") as XmlElement;
                xe.SetAttribute("Name", field.Field.Name);
                var value = string.Join(",", field.Value.Select(v => v.Id).ToArray());
                xe.SetAttribute("Value", value);
                rootnode.AppendChild(xe);
            }

            if (this.picManager.Images != null)
            {
                foreach (var bitmap in this.picManager.Images)
                {
                    string picbase64 = getBase64Pic(bitmap);
                    xe = xmldoc.CreateNode(XmlNodeType.Element, "Pic", "") as XmlElement;
                    XmlCDataSection picdata = xmldoc.CreateCDataSection(picbase64);
                    xe.AppendChild(picdata);
                    xmldoc.SelectSingleNode("/Clipping/CapPictures").AppendChild(xe);
                }
            }


            xe = xmldoc.CreateNode(XmlNodeType.Element, "Field", "") as XmlElement;
            xe.SetAttribute("Name", "addedBy");

            UserInfo user = UserInfoProvider.GetInstance().TryGetUserInfoByName(this.userSetting.UserName);
            if (user != null)
                xe.SetAttribute("Value", user.UserId);
            else
                xe.SetAttribute("Value", this.userSetting.UserName);
            rootnode.AppendChild(xe);

            string html = this.htmlEditor.ContentHtml;
            if (html == null)
                html = "";
            string txt = this.htmlEditor.ContentText;
            if (txt == null)
                txt = "";
            XmlCDataSection cdata = xmldoc.CreateCDataSection(html);
            xmldoc.SelectSingleNode("/Clipping/ContentHtml").AppendChild(cdata);
            cdata = xmldoc.CreateCDataSection(txt);
            xmldoc.SelectSingleNode("/Clipping/ContentTxt").AppendChild(cdata);
            if (this.sysSetting.EmbedPic)
            {
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(html);
                var imgNav = doc.CreateNavigator();
                var lis = imgNav.Select("//img");

                string link = getFirstLink();
                while (lis.MoveNext())
                {
                    string picUrl = string.Empty;
                    try
                    {
                        picUrl = lis.Current.GetAttribute("src", null);
                        string picbase64 = getBase64Pic(picUrl, link);
                        xe = xmldoc.CreateNode(XmlNodeType.Element, "Pic", "") as XmlElement;
                        XmlCDataSection picdata = xmldoc.CreateCDataSection(picbase64);
                        xe.SetAttribute("url", picUrl);
                        xe.AppendChild(picdata);
                        xmldoc.SelectSingleNode("/Clipping/Pictures").AppendChild(xe);
                    }
                    catch (Exception ex)
                    {
                        this.logHelper.LogWarnMsg(ex, "获取图片异常，网页：{1},图片：{0}", picUrl, link);
                    }
                }
            }
            return xmldoc;
        }




        /// <summary>
        /// 将剪报保存在本地
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        private bool saveClippingLocal(XmlDataDocument doc, out string file)
        {
            string url = getFirstLink();
            string folder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Clippings");
            try
            {
                if (!System.IO.Directory.Exists(folder))
                {
                    System.IO.Directory.CreateDirectory(folder);
                }

                string fileName = string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), ClippingHelper.Md5Hash(url).Replace("-", ""));
                if (this.sysSetting.ZipClipping)
                {
                    var content = Encoding.GetEncoding(this.sysSetting.Encoding).GetBytes(doc.InnerXml);
                    file = System.IO.Path.Combine(folder, string.Format("{0}.zip", fileName));
                    using (ZipFile zip = new ZipFile())
                    {
                        zip.AddEntry(string.Format("{0}.xml", fileName), content);
                        zip.Save(file);
                    }
                }
                else
                {
                    file = System.IO.Path.Combine(folder, string.Format("{0}.xml", fileName));
                    System.IO.File.WriteAllText(file, doc.InnerXml, Encoding.GetEncoding(this.sysSetting.Encoding));
                }
                return true;
            }
            catch (Exception ex)
            {
                file = null;
                return false;
            }
        }
        /// <summary>
        /// 上传剪报
        /// </summary>
        /// <param name="filename"></param>
        private bool uploadClipping(string filename)
        {
            try
            {
                WebClient wc = new WebClient();

                if (this.sysSetting.UploadUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
                {

                    string uploadurl = string.Format("{0}?user={1}&pwd={2}", this.sysSetting.UploadUrl, this.sysSetting.UploadUserName, this.sysSetting.UploadPassword);
                    wc.Credentials = new NetworkCredential(this.sysSetting.UploadUserName, this.sysSetting.UploadPassword);

                    wc.UploadFile(uploadurl, filename);
                    return true;
                }
                else if (this.sysSetting.UploadUrl.StartsWith("ftp", StringComparison.OrdinalIgnoreCase))
                {
                    FileInfo fi = new FileInfo(filename);
                    string uploadurl = string.Format("{0}/{1}", this.sysSetting.UploadUrl, fi.Name);
                    wc.Credentials = new NetworkCredential(this.sysSetting.UploadUserName, this.sysSetting.UploadPassword);

                    wc.UploadFile(uploadurl, filename);
                    return true;

                }
                else { return false; }
            }
            catch (Exception ex)
            {
                this.logHelper.LogErrMsg(ex, "上传剪报失败");
                return false;
            }
        }

        /// <summary>
        /// 更新上传历史
        /// </summary>
        private void updateHistory()
        {
            try
            {
                Clipping.Utils.UploadHistoryRepository rep = new Clipping.Utils.UploadHistoryRepository();
                var links = getLinks();
                foreach (var link in links)
                {


                    foreach (var category in this.categorySelector.SelectedCategories)
                    {
                        rep.AddHistory(
                            new UploadHistory()
                            {
                                Url = link,
                                ClientId = category.Id
                            }
                             );
                    }
                }
            }
            catch (Exception ex)
            {
                this.logHelper.LogErrMsg(ex, "更新上传历史");
            }
        }


        private string getBase64Pic(string picUrl, string refererUrl)
        {
            if (string.IsNullOrEmpty(picUrl))
                return "";
            WebClient wc = new WebClient();
            wc.Headers.Add(HttpRequestHeader.Referer, refererUrl);
            wc.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.CacheIfAvailable);
            try
            {
                byte[] data = wc.DownloadData(picUrl);
                if (data.Length > 0)
                    return Convert.ToBase64String(data);
                else
                    return "";
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private string getBase64Pic(Bitmap bitmap)
        {
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] imageBytes = stream.ToArray();
            string base64String = Convert.ToBase64String(imageBytes);
            return base64String;
        }

     


    }
}
